﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AffordoPlugin.ElectronicScale;
using AffordoPlugin.Enum;
using AffordoPlugin.Model;
using AffordoPlugin.Print;
using Fleck;
using Newtonsoft.Json;

namespace AffordoPlugin.Fleck
{
	public class FleckWebSocketServer
	{
		public string ElectronicScaleData;
		public void Start()
		{
			try
			{
				var port = Helper.ConfigurationHelper.GetAppSettingValue("port");

				if (string.IsNullOrEmpty(port))
				{
					throw new Exception("端口不存在");
				}

				IDictionary<string, IWebSocketConnection> dicSockets = new Dictionary<string, IWebSocketConnection>();

				var server = new WebSocketServer($"ws://127.0.0.1:{port}");
				server.RestartAfterListenError = true;

				server.Start(socket =>
				{
					socket.OnOpen = () =>
					{
						var clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
						dicSockets.Add(clientUrl, socket);
					};
					socket.OnMessage = (message) =>
					{
						var clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
						Helper.LogHelper.Error(clientUrl + "\t" + message);

						if (!message.Contains("messageType"))
						{
							return;
						}

						try
						{
							

							var dymicObj = JsonConvert.DeserializeObject<dynamic>(message);
				
								switch ((MessageTypeEnum)dymicObj.messageType)
								{
									case MessageTypeEnum.ElectronicScale:
										{
										var messageObj = JsonConvert.DeserializeObject<Model.Message<ElectrinicSaleContent>>(message);

											ElectronicScaleData = "";
											var obj = new ElectronicScaleUtil();
											obj.ElectronicDataDelegate += GetData;
											obj.Run(messageObj);
											var tryTimes = 0;
											do
											{
												if (!string.IsNullOrEmpty(ElectronicScaleData))
												{
													var msg = GetMessage(ElectronicScaleData, true, "", "ElectronicScale");
													socket.Send(msg);
													break;
												}
												else
												{
													Thread.Sleep(200);
													tryTimes++;
												}
											} while (tryTimes < 5);

										}
										break;

									case MessageTypeEnum.PrintDevice:
										{
											var printers = new PrintUtil().GetPrintDevice();
											var msg = GetMessage(printers, true, "", "PrintDevice");
											socket.Send(msg);
										}
										break;

									case MessageTypeEnum.Print:
										{
										var messageObj = JsonConvert.DeserializeObject<Model.Message<PrintContent>>(message);

										var success = new PrintUtil().Print(messageObj);

											if (!success)
											{
												var msg = GetMessage("", false, "打印失败", "Print");
												socket.Send(msg);
											}
											else
											{
												var msg = GetMessage("", true, "打印成功", "Print");
												socket.Send(msg);
											}
										}
										break;
									case MessageTypeEnum.SerialPort:
										{
											var portNames = new ElectronicScaleUtil().GetPortNames();
											var msg = GetMessage(portNames, true, "", "SerialPort");
											socket.Send(msg);
										}
										break;
									case MessageTypeEnum.Barcode:
										{
										var messageObj = JsonConvert.DeserializeObject<Model.Message<BarcodeContent>>(message);

										var base64 = new BarcodeUtil().GetBarCode(messageObj);
											var msg = GetMessage(base64, true, "", "Barcode");
											socket.Send(msg);
										}
										break;
									default:
										{
											var msg = GetMessage($"未知消息类型:{dymicObj.messageType}", false, "","");
											socket.Send(msg);
										}
										break;
								}
						
						}
						catch (Exception ex)
						{
							Helper.LogHelper.Error(ex.Message + ex.InnerException?.Message ?? "");
							var msg = GetMessage(ex.Message+ex.InnerException?.Message??"", false, "", "Exception");
							socket.Send(msg);
						}
					};
					socket.OnClose = () =>
					{
						var clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
						if (dicSockets.ContainsKey(clientUrl))
						{
							dicSockets.Remove(clientUrl);
						}
					};
				});
			}
			catch (Exception ex)
			{
				Helper.LogHelper.Error("FleckWebSocket异常" + ex.Message + ex.InnerException?.Message ?? "");

				return;
			}

		}

		private void GetData(string data)
		{
			ElectronicScaleData = data;
		}

		private string GetMessage<T>(T body, bool success, string msg,string messageType)
		{
			var message = new SendMessage<T>();

			message.success = success;
			message.msg = msg;
			message.data = body;
			message.messageType = messageType;

			return JsonConvert.SerializeObject(message);
		}
	}
}
